package cn.s1995.sloth.common.core.util;

import cn.hutool.core.util.StrUtil;
import cn.s1995.sloth.common.core.constant.enums.file.ExcelType;
import cn.s1995.sloth.common.core.constant.enums.file.ImageType;
import cn.s1995.sloth.common.core.constant.enums.file.VideoType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * FileUtil
 *
 * @Author penf
 * @Description
 * @Date 2023/08/12 02:14
 */
@Slf4j
@UtilityClass
public class FileUtils {

    public static void main(String[] args) {
        // String startfile = "C:\\Users\\DELL\\Pictures\\壁纸\\微信图片_202104251637581.jpg";
        // String tofile = "C:\\Users\\DELL\\Pictures\\寻迹.jpg";
        //
        // byte[] bytes = file2byte(startfile);
        // System.out.println(bytes);
        //
        // File file = byte2file(bytes, tofile);
        // System.out.println(file);


        String rootPath = "E:\\projects\\code-824\\sloth-fast"; // Set your root directory path
        String targetFolderName = "sloth"; // The folder name you want to change
        String newFolderName = "sloth"; // The new name for the folder

        File rootDir = new File(rootPath);
        renameFoldersRecursively(rootDir, targetFolderName, newFolderName);
        System.out.println("Folder renaming completed.");
    }

    /**
     * 递归重命名文件夹
     * @param dir
     * @param targetName
     * @param newName
     */
    private static void renameFoldersRecursively(File dir, String targetName, String newName) {
        if (!dir.isDirectory()) {
            return; // Not a directory, skip
        }

        // If the directory matches the target name, rename it
        if (dir.getName().equalsIgnoreCase(targetName)) {
            File newDir = new File(dir.getParent(), newName);
            if (dir.renameTo(newDir)) {
                System.out.println("Renamed: " + dir + " to " + newDir);
                dir = newDir; // Update reference to point to the renamed directory
            }
        }

        // Recursively rename subdirectories
        File[] subDirs = dir.listFiles(File::isDirectory);
        if (subDirs != null) {
            for (File subDir : subDirs) {
                renameFoldersRecursively(subDir, targetName, newName);
            }
        }
    }

    /**
     * 转换文件
     * @param multipartFile
     * @return
     */
    public static File convertToFile(MultipartFile multipartFile) {
        File convFile = new File(multipartFile.getOriginalFilename());
        try {
            multipartFile.transferTo(convFile);
        } catch (IOException e) {
            log.error("multipartFile转File失败", e);
            throw new RuntimeException(e);
        }
        return convFile;
    }

    /**
     * File转byte[]数组
     *
     * @param fileFullPath
     * @return
     */
    public static byte[] file2byte(String fileFullPath) {
        if (fileFullPath == null || "".equals(fileFullPath)) {
            return null;
        }
        return file2byte(new File(fileFullPath));
    }

    /**
     * File转byte[]数组
     *
     * @param file
     * @return
     */
    public static byte[] file2byte(File file) {
        if (file == null) {
            return null;
        }
        FileInputStream fileInputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fileInputStream.read(b)) != -1) {
                byteArrayOutputStream.write(b, 0, n);
            }
            return byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.close();
                }
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    /**
     * byte[]数组转File
     *
     * @param bytes
     * @param fileFullPath
     * @return
     */
    public static File byte2file(byte[] bytes, String fileFullPath) {
        if (bytes == null) {
            return null;
        }
        FileOutputStream fileOutputStream = null;
        try {
            File file = new File(fileFullPath);
            // 判断文件是否存在
            if (file.exists()) {
                file.mkdirs();
            }
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(bytes);
            return file;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException ioe) {
                    log.error(ioe.getMessage(), ioe);
                }
            }
        }
        return null;
    }


    /**
     * 从json文件中读取数据
     * @param file
     * @param tClass
     * @return
     * @param <T>
     */
    public static <T> List<T> readJsonData(File file, Class<T> tClass) {
        List<T> records = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                try {
                    T record = mapper.readValue(line, tClass);
                    records.add(record);
                } catch (JsonProcessingException e) {
                    System.err.println("Error processing JSON line: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return records;
    }

    /**
     * 获取文件扩展名, 无法找到返回 ""
     *
     * @param fileName
     * @return
     */
    public static String getExt(String fileName) {
        if (fileName != null) {
            int i = fileName.lastIndexOf(".");
            if (i != -1) {
                return fileName.substring(i + 1).toLowerCase();
            }
        }
        return "";
    }

    /**
     * 去除文件扩展名(包括 '.')
     *
     * @param fileName
     * @return
     */
    public static String rmExt(String fileName) {
        if (fileName != null) {
            int i = fileName.lastIndexOf(".");
            if (i != -1) {
                return fileName.substring(0, i);
            }
        }
        return "";
    }

    /**
     * 校验是否是图片
     *
     * @param ext
     * @return
     */
    public static boolean isImage(String ext) {
        try {
            ImageType.valueOf(ext.toLowerCase());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 校验是否是视频
     *
     * @param ext
     * @return
     */
    public static boolean isVideo(String ext) {
        try {
            if (ext.contains(StrUtil.DOT)) {
                ext = getExt(ext);
            }
            VideoType.valueOf(ext.toLowerCase());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 校验是否是Excel
     *
     * @param ext
     * @return
     */
    public static boolean isExcel(String ext) {
        try {
            ExcelType.valueOf(ext.toLowerCase());
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
